﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using YJKSparseDistance.Properties;

namespace YJKSparseDistance
{
	public static class InsetDataUtility
	{
		public static bool TryGetAddedValue(string inputGuid, Area input, out List<string> addedValue, out Entity usedEntity)
		{
			addedValue = new List<string>();
			Guid guid = new Guid(inputGuid);
			Document document = input.Document;
			Schema schema = Schema.Lookup(guid);
			Type typeFromHandle = typeof(InsertData);
			usedEntity = null;
			if (schema != null && schema.SchemaName.Equals(Resources.Str_SchemaName))
			{
				Entity entity = input.GetEntity(schema);
				if (entity != null && entity.Schema != null)
				{
					foreach (FieldInfo fieldInfo in typeFromHandle.GetFields())
					{
						Field field = schema.GetField(fieldInfo.Name);
						if (fieldInfo.FieldType == typeof(List<string>))
						{
							usedEntity = entity;
							addedValue = entity.Get<IList<string>>(field).ToList<string>();
							return true;
						}
					}
				}
			}
			return false;
		}

		public static bool TryWriteToElement(string inputGuid, Area inputArea, InsertData inputValue)
		{
			Guid guid = new Guid(inputGuid);
			Document document = inputArea.Document;
			Schema schema = Schema.Lookup(guid);
			Type typeFromHandle = typeof(InsertData);
			Transaction transaction = new Transaction(document, "WriteExtensibleStorage");
			List<string> lstInsetData = inputValue.m_lstInsetData;
			List<string> collection = new List<string>();
			Entity entity = null;
			if (InsetDataUtility.TryGetAddedValue(inputGuid, inputArea, out collection, out entity))
			{
				lstInsetData.AddRange(collection);
			}
			if (schema != null && schema.SchemaName.Equals(Resources.Str_SchemaName))
			{
				if (entity == null)
				{
					entity = new Entity(schema);
				}
				try
				{
					transaction.Start();
					foreach (FieldInfo fieldInfo in typeFromHandle.GetFields())
					{
						Field field = schema.GetField(fieldInfo.Name);
						if (fieldInfo.FieldType.Name.Equals(typeof(List<string>).Name))
						{
							entity.Set<IList<string>>(field, lstInsetData.ToArray());
						}
					}
					inputArea.SetEntity(entity);
					transaction.Commit();
					return true;
				}
				catch (Exception)
				{
					if (transaction.HasStarted())
					{
						transaction.RollBack();
					}
					return false;
				}
				return false;
			}
			return false;
		}
	}
}
